package com.umgsai.wx.backend.util;

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.util.Date;

public class JodaTimeUtil {

    public static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String MILLS_NUMBER_FORMAT = "yyyyMMddHHmmssSSS";
    public static final String MILLS_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String YEAR_MONTH_FORMAT = "yyyy-MM";
    public static final String HOUR_MINUTE_FORMAT = "HH:mm";
    public static final String DATE_HOUR_MINUTE_FORMAT = "yyyy-MM-dd HH:mm";

    public static String format(Date date) {
        DateTime dateTime = new DateTime(date);
        return dateTime.toString(STANDARD_FORMAT);
    }

    public static String format(Date date, String format) {
        DateTime dateTime = new DateTime(date);
        return dateTime.toString(format);
    }

    public static Date parseDate(String dateTimeStr) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(STANDARD_FORMAT);
        DateTime dateTime = dateTimeFormatter.parseDateTime(dateTimeStr);
        return dateTime.toDate();
    }

    public static Date parseDate(String dateTimeStr, String format) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(format);
        DateTime dateTime = dateTimeFormatter.parseDateTime(dateTimeStr);
        return dateTime.toDate();
    }

    public static Date getBeginTimeOfDay(Date date) {
        DateTime dateTime = new DateTime(date);
        return dateTime.withTimeAtStartOfDay().toDate();
    }

    public static Date getEndTimeOfDay(Date date) {
        DateTime dateTime = new DateTime(date);
        return dateTime.millisOfDay().withMaximumValue().toDate();
    }

    public static Date addYear(Date date, int year) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusYears(year).toDate();
    }

    public static Date addMonth(Date date, int month) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusMonths(month).toDate();
    }

    public static Date addDay(Date date, int day) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusDays(day).toDate();
    }

    public static int getDayOfWeek(Date date) {
        DateTime dateTime = new DateTime(date);
        return dateTime.getDayOfWeek();
    }

    public static Date getBeginTimeOfMonth(Date date) {
        DateTime dateTime = new DateTime(date);
        Date beginDateOfMonth = dateTime.dayOfMonth().withMinimumValue().toDate();
        return getBeginTimeOfDay(beginDateOfMonth);
    }

    public static Date getEndTimeOfMonth(Date date) {
        DateTime dateTime = new DateTime(date);
        Date endDateOfMonth = dateTime.dayOfMonth().withMaximumValue().toDate();
        return getEndTimeOfDay(endDateOfMonth);
    }

    public static Date getBeginTimeOfWeek(Date date) {
        DateTime dateTime = new DateTime(date);
        Date beginDateOfMonth = dateTime.dayOfWeek().withMinimumValue().toDate();
        return getBeginTimeOfDay(beginDateOfMonth);
    }

    public static Date getEndTimeOfWeek(Date date) {
        DateTime dateTime = new DateTime(date);
        Date endDateOfMonth = dateTime.dayOfWeek().withMaximumValue().toDate();
        return getEndTimeOfDay(endDateOfMonth);
    }

    public static Date getBeginTimeOfYear(Date date) {
        DateTime dateTime = new DateTime(date);
        Date beginDateOfMonth = dateTime.dayOfYear().withMinimumValue().toDate();
        return getBeginTimeOfDay(beginDateOfMonth);
    }

    public static Date getEndTimeOfYear(Date date) {
        DateTime dateTime = new DateTime(date);
        Date endDateOfMonth = dateTime.dayOfYear().withMaximumValue().toDate();
        return getEndTimeOfDay(endDateOfMonth);
    }

    public static int getDaysBetween(Date date1, Date date2) {
        DateTime dateTime1 = new DateTime(date1);
        DateTime dateTime2 = new DateTime(date2);
        return Days.daysBetween(dateTime1, dateTime2).getDays();
    }

    public static void main(String[] args) {
        System.out.println(JodaTimeUtil.format(new Date()));
        System.out.println(JodaTimeUtil.parseDate("2023-03-11 11:34:04"));
        System.out.println(JodaTimeUtil.parseDate("2023-03-11", DATE_FORMAT));

        Date beginTimeOfDay = JodaTimeUtil.getBeginTimeOfDay(new Date());
        System.out.printf("beginTimeOfDay: %s \n", new DateTime(beginTimeOfDay).toString(MILLS_FORMAT));

        Date endTimeOfDay = JodaTimeUtil.getEndTimeOfDay(new Date());
        System.out.printf("endTimeOfDay: %s \n", new DateTime(endTimeOfDay).toString(MILLS_FORMAT));

        DateTime dateTime2 = new DateTime(2020, 2, 1, 10, 13, 14);
        System.out.printf("dateTime2: %s \n", dateTime2.toString(MILLS_FORMAT));

        Date date = addYear(new Date(), 2);
        System.out.println(JodaTimeUtil.format(date));
        date = addYear(new Date(), -4);
        System.out.println(JodaTimeUtil.format(date));
        date = addMonth(new Date(), 2);
        System.out.println(JodaTimeUtil.format(date));
        date = addDay(new Date(), 3);
        System.out.println(JodaTimeUtil.format(date));

        System.out.println(getDayOfWeek(new Date()));
        System.out.println(getDayOfWeek(addDay(new Date(), 1)));
        System.out.println(getDayOfWeek(addDay(new Date(), 2)));
        System.out.println(getDayOfWeek(addDay(new Date(), 3)));
        System.out.println(getDayOfWeek(addDay(new Date(), 4)));
        System.out.println(getDayOfWeek(addDay(new Date(), 5)));
        System.out.println(getDayOfWeek(addDay(new Date(), 6)));

        System.out.println(getBeginTimeOfMonth(new Date()));
        System.out.println(getEndTimeOfMonth(new Date()));
        System.out.println(getBeginTimeOfWeek(new Date()));
        System.out.println(getEndTimeOfWeek(new Date()));
        System.out.println(getBeginTimeOfYear(new Date()));
        System.out.println(getEndTimeOfYear(new Date()));

        Date date1 = JodaTimeUtil.parseDate("2023-03-11 23:59:59");
        Date date2 = JodaTimeUtil.parseDate("2023-03-12 00:00:01");
        System.out.println(getDaysBetween(getBeginTimeOfDay(date1), getBeginTimeOfDay(date2)));
    }
}
